package org.kongqian.org.service.impl;

import org.apache.logging.log4j.util.Strings;
import org.kongqian.basic.common.SendMail;
import org.kongqian.basic.constants.BaseConstants;
import org.kongqian.basic.utils.AjaxResult;
import org.kongqian.basic.utils.RedisUtils;
import org.kongqian.org.domain.Employee;
import org.kongqian.org.domain.Shop;
import org.kongqian.org.domain.ShopAuditLog;
import org.kongqian.org.dto.AuditShopDTO;
import org.kongqian.org.mapper.EmployeeMapper;
import org.kongqian.org.mapper.ShopMapper;
import org.kongqian.org.service.IBaiduAuditService;
import org.kongqian.org.service.IShopAuditLogService;
import org.kongqian.org.service.IShopService;
import org.kongqian.basic.service.impl.BaseServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.mail.MessagingException;
import java.util.Date;
import java.util.Objects;
import java.util.UUID;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author kq
 * @since 2022-11-01
 */
@Service
public class ShopServiceImpl extends BaseServiceImpl<Shop> implements IShopService {

    @Autowired
    private ShopMapper shopMapper;

    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private IBaiduAuditService baiduAuditService;

    @Autowired
    private IShopAuditLogService shopAuditLogService;

    @Autowired
    private SendMail sendMail;

    @Override
    @Transactional
    public void settledIn(Shop shop) {
        Shop shopMessage=shopMapper.selectByName(shop.getName());
        extracted(shop, shopMessage);

        //保存店铺信息 根据查出来的店铺信息来判断是否为空，不为空且状态为4驳回，就用该店铺信息来修改即可
        if (Objects.nonNull(shopMessage) && shopMessage.getState().equals(BaseConstants.Shop.STATE_REJECT_AUDIT)){
            //根据查询出来的店铺id来修改shop的id
            shop.setId(shopMessage.getId());
        }
        //修改店铺的状态
        shop.setState(BaseConstants.Shop.STATE_WAIT_AUTID);
        //申请的时间
        shop.setRegisterTime(new Date());
        //如果shop的id有值就是修改，否则就是新增
        if (shop.getId()!=null){
            shopMapper.updateById(shop);
        }else {
            shopMapper.insert(shop);
        }


        //保存管理员信息
        Employee employee = shop.getEmployee();
        //判断管理员是否存在，存在就用已经有的，设置id 根据id修改
        Employee  employeeMessage=employeeMapper.selectByUsername(employee.getUsername());
        if (Objects.nonNull(employeeMessage)){
            employee.setId(employeeMessage.getId());
        }else {
            //如果是新增店铺管理员，状态应该是待激活
            employee.setState(BaseConstants.Employee.STATE_WAIT_AUTID);
            employee.setShopId(shop.getId());
            employeeMapper.insert(employee);
        }
        //开启自动审核 通过就将店铺状态改为待激活并发送邮件激活，不然就驳回和发邮件提示驳回原因
            //拼接一下审核参数
        String text=shop.getName()+" "+shop.getAddress();
        AjaxResult ajaxResult = baiduAuditService.baiduAudit(text, null, null);
        if (ajaxResult.getSuccess()){
            //通过
            //修改状态
            shop.setState(BaseConstants.Shop.STATE_WAIT_ACTIVE);

            //做激活码和保存到redis
            UUID uuid = UUID.randomUUID();
            RedisUtils instance = RedisUtils.INSTANCE;
            String id=shop.getId()+"";
            instance.set(uuid.toString(), id, 1800);


            //发邮件激活
//            String content="<a href='http://localhost:80/shop/activation/"+shop.getId()+"/"+uuid+"'>激活店铺</a>";
            String content="<a href='http://localhost:80/shop/activation/"+uuid+"'>激活店铺</a>";
            try {
                sendMail.send(shop.getName(), content, shop.getEmployee().getEmail());
            } catch (MessagingException e) {
                e.printStackTrace();
            }
        }else {
            shop.setState(BaseConstants.Shop.STATE_REJECT_AUDIT);
            //发邮件提示
        }
        //根据修改后或者新增的管理员id修改店铺的管理员id
        shopMapper.updateById(shop);

        //审核后保存审核日志
        ShopAuditLog shopAuditLog = new ShopAuditLog();
        shopAuditLog.setState(ajaxResult.getSuccess() ? 1:0);
        shopAuditLog.setShopId(shop.getId());
        shopAuditLog.setAuditTime(new Date());
        shopAuditLog.setNote(ajaxResult.getSuccess() ?"审核通过":"审核失败"+ajaxResult.getMessage());
        shopAuditLogService.insert(shopAuditLog);
    }

    @Override
    public void activationShop(String uuid) {
        //从redis中获取id
        RedisUtils instance = RedisUtils.INSTANCE;

        //如果激活过期就抛异常
        if (instance.get(uuid)==null){
            throw new RuntimeException("error message!");
        }
        String s = instance.get(uuid);
        long id = Long.parseLong(s);

        //根据id查shop信息
        Shop shop = shopMapper.selectById(id);

        System.out.println(shop);
        //创建shop对象
        Shop activation = new Shop();

        //将查出来的数据赋值给新的
        BeanUtils.copyProperties(shop,activation);
        activation.setState(BaseConstants.Shop.STATE_ACTIVE_SUCCESS);

        //设置管理员id
        Long adminId = shop.getAdminId();
        Employee employee = new Employee();
        employee.setId(adminId);
        activation.setEmployee(employee);

        shopMapper.updateById(activation);

        //修改管理员状态为激活
        Employee employee1=employeeMapper.selectByShopId(id);
        Employee employee2 = new Employee();
        BeanUtils.copyProperties(employee1, employee2);
        employee2.setState(BaseConstants.Employee.STATE_NORMAL);
        employee2.setShopId(employee1.getShopId());
        employeeMapper.updateById(employee2);
    }

    @Override
    public void auditMessage(AuditShopDTO dto) {
        //更改shop的状态
        Shop shop = shopMapper.selectById(dto.getId());
        Shop audioShop = new Shop();
        BeanUtils.copyProperties(shop, audioShop);
        audioShop.setState(dto.getState());
        shopMapper.updateById(audioShop);

        //审核记录
        if (Objects.nonNull(dto.getNote())) {
            ShopAuditLog shopAuditLog = new ShopAuditLog();
            shopAuditLog.setShopId(shop.getId());
            shopAuditLog.setAuditTime(new Date());
            shopAuditLog.setNote(dto.getNote());
            shopAuditLogService.insert(shopAuditLog);
        }
    }

    private void extracted(Shop shop, Shop shopMessage) {
        //1.校验
        //1.1前端参数和必填数据校验
        if (Objects.isNull(shop)){
            throw new RuntimeException("error message!");
        }
        if (Strings.isEmpty(shop.getName()) || Strings.isEmpty(shop.getTel()) || Strings.isEmpty(shop.getAddress())){
            throw new RuntimeException("error message!");
        }
        Employee employee = shop.getEmployee();
        if (Strings.isEmpty(employee.getUsername()) || Strings.isEmpty(employee.getPhone()) ||Strings.isEmpty(employee.getEmail())
                ||Strings.isEmpty(employee.getPassword()) ||Strings.isEmpty(employee.getConfirmPassword())){
            throw new RuntimeException("error message!");
        }
        //1.2密码校验
        if (!employee.getPassword().equals(employee.getConfirmPassword())){
            throw new RuntimeException("error message!");
        }
        //1.3店铺校验
        //店铺存在
        if (Objects.nonNull(shopMessage) && !shopMessage.getState().equals(BaseConstants.Shop.STATE_REJECT_AUDIT)){
            throw new RuntimeException("该店铺已经存在!");
        }

        //前端格式校验
        //店铺校验
        if (!shop.getName().matches("[a-zA-Z\u4E00-\u9FA5]{2,8}$")){
            throw new RuntimeException("店铺名至少输入2-8之间的英文或汉字");
        }

        //电话校验
        if (!shop.getTel().matches("^((13[0-9])|(14[0-9])|(15[0-9])|(17[0-9])|(18[0-9]))\\d{8}$")){
            throw new RuntimeException("您输入的电话格式不对，请重新输入！");
        }

        //电话校验
        if (!shop.getEmployee().getPhone().matches("^((13[0-9])|(14[0-9])|(15[0-9])|(17[0-9])|(18[0-9]))\\d{8}$")){
            throw new RuntimeException("您输入的电话格式不对，请重新输入！");
        }

        //账号校验
        if (!shop.getEmployee().getUsername().matches("^[a-zA-Z0-9_-]{4,16}$")){
            throw new RuntimeException("请输入4到16位的账号（字母，数字，下划线，减号！");
        }

        //密码强度校验
        if (!shop.getEmployee().getPassword().matches("^.*(?=.{6,})(?=.*\\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%^&*? ]).*$")){
            throw new RuntimeException("密码最少6位，包括至少1个大写字母，1个小写字母，1个数字，1个特殊字符！");
        }
    }
}
